import math
from unit import *
from ui import *

class Weapon:
    def __init__(self, t, source, target, db):
        self.type = t
        self.source = source
        self.target = target
        self.dead = False
        self.db = db
        self.vel = self.get_vel_vec()
        self.armor_damage = self.get_armor_damage()
        self.shield_damage = self.get_shield_damage()
        self.image, self.rect = load_png('bullet.png')

    def get_vel_vec(self):
        dist = math.sqrt((self.source.pos[0] - self.target.pos[0])*(self.source.pos[0] - self.target.pos[0])+(self.source.pos[1] - self.target.pos[1])*(self.source.pos[1] - self.target.pos[1]))
        unit_vel = ((self.target.pos[0] - self.source.pos[0])/dist, (self.target.pos[1] - self.source.pos[1])/dist)
        return (unit_vel[0]*self.get_vel(), unit_vel[1]*self.get_vel())

    def get_vel(self):
        return 20.0

    def get_armor_damage(self):
        return 10

    def get_shield_damage(self):
        return 10
		
    def receive_message(self):
        """
        called by weapondb every tick
        """
        pass
		
    def tick(self):
        self.move()
        
    def check_collide(self):
        """
        detects collision of weapon with a person
        """
        dist = self.get_vel()
        for i in range(1,dist):
            point = ((self.pos[0] - self.oldpos[0])*i/dist, 
                    (self.pos[1] - self.oldpos[1])*i/dist)
            for unit in self.unit_db:
                if unit.rect.collidepoint(point):
                    self.target = unit
                    self.pos = self.target.pos
                    self.dead = True
                    return

    def move(self): 
        #if self.no_collide():
        if self.dead:
            self.at_target(self.target)
        self.oldpos = self.pos
        self.pos = (self.pos[0]+self.vel[0], self.pos[1]+self.vel[1])
        self.check_collide()
            #x1, y1 = self.target.pos[0], self.target.pos[1]
            #x2, y2 = self.pos[0], self.pos[1]
            #d = math.sqrt((x2 - x1)*(x2 - x1) + (y2 - y1)*(y2 - y1))
            #if d < self.vel:
                #self.pos = self.target.pos
            #else:
                #self.pos = ((x1 - x2)/d*self.vel+x2, (y1 - y2)/d*self.vel+y2)

    def at_target(self, unit):
        self.damage(unit)
        self.die()

    def die(self):
        self.db.del_weapon


class UIWeapon(Weapon):
    def __init__(self, t, source, target):
        pygame.sprite.Sprite.__init__(self)
        Weapon.__init__(self, t, source, target)
        self.image, self.rect = load_png('image.png')
        self.sprite_pos = self.old_pos = self.pos = source.pos
        self.selected = 0

    def move(self):
        """Moves and updates sprite location."""
        self.sprite_pos = self.old_pos = self.pos
        Weapon.move(self)

    def graphics_tick(self, screen, tdelta):
        """Moves and update sprite between client ticks."""
        if self.rect.center != self.pos:
            self.rect.center = self._graphics_move(tdelta)
        screen.blit(self.image, self.rect)

    def _graphics_move(self, tdelta, tick):
        """Calculates position change between client ticks."""
        calc = lambda i: self.sprite_pos[i] + (self.pos[i] -
                self.old_pos[i])*(tdelta/tick)
        self.sprite_pos = calc(0), calc(1)
        return self.sprite_pos


class WeaponDB(UnitDB):
    """
    Database to store and manage Weapons
    """
    def __init__(self):
        UnitDB.__init__(self)
	
    def add_weapon(self, type, source, target):
        self.units.append(Weapon(type, source, target))

    def del_weapon(self, id):
        self.units.remove[id]

class UIWeaponDB(WeaponDB):
    """
    WeaponDB derived from base class, reimplemented to use UIWeapons
    """
    def __init__(self):
        WeaponDB.__init__(self)

    def add_weapon(self, type, source, target):
        self.units.append(UIWeapon(type, source, target))

    def del_weapon(self, id):
        self.units.remove[id]
